package com.ddwl.goods.service;

import cn.hutool.core.util.StrUtil;
import com.ddwl.common.constant.BaseEnum;
import com.ddwl.common.constant.Constant;
import com.ddwl.common.constant.GoodsEnum;
import com.ddwl.common.exception.CommonException;
import com.ddwl.common.exception.ExceptionCode;
import com.ddwl.common.exception.ParamException;
import com.ddwl.common.feign.api.ShopApi;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.MySqlUtil;
import com.ddwl.common.util.ObjectUtil;
import com.ddwl.common.util.UUIDGenerator;
import com.ddwl.goods.dao.CategoryDao;
import com.ddwl.goods.dao.ItemDao;
import com.ddwl.goods.mapper.CategoryMapper;
import com.ddwl.goods.model.Category;
import com.ddwl.goods.model.Item;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.goods.CategoryBo;
import com.ddwl.schema.bo.goods.CategorySearchBo;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.goods.CategoryVo;
import com.ddwl.schema.vo.shop.ShopVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Fu Zhaohui
 * @version 1.0.0
 * @date 2019/8/8 14:00
 */
@Service
public class CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Resource
    private CategoryDao categoryDao;

    @Autowired
    private ItemDao itemDao;
    @Resource
    private ShopApi shopApi;

    @Transactional(rollbackFor = Throwable.class)
    public String create(CategoryBo bo) {
        ShopVo shopVo = shopApi.getDefaultShopForApi().getResult();
        String code = getParentCode(bo.getPid());
        Category entity = new Category();
        BeanUtils.copyProperties(bo, entity);
        entity.setId(UUIDGenerator.getShortUUID());
        if (null != shopVo) {
            entity.setShopId(shopVo.getId());
        }
        entity.setCategoryCode(code + entity.getId());
        entity.setCategoryType(GoodsEnum.CategoryTypeEnum.PLATFORM.getCode());
        entity.setEffect(BaseEnum.StatusEnum.ENABLE.getCode());
        categoryDao.insert(entity);
        return entity.getId();
    }

    @Transactional(rollbackFor = Throwable.class)
    public void update(CategoryBo bo) {
        ParamException.isTrue((StrUtil.isNotEmpty(bo.getPid()) && bo.getPid().equals(bo.getId())), "父节点不能选择自己");
        Category entity = categoryDao.selectByPrimaryKey(bo.getId());
        if (entity == null) {
            throw new CommonException(ExceptionCode.DATA_NOT_EXISTS);
        }
        String code = getParentCode(bo.getPid());
        BeanUtils.copyProperties(bo, entity, ObjectUtil.getNullFields(bo));
        entity.setCategoryCode(code + entity.getId());
        categoryDao.updateByPrimaryKeySelective(entity);
        //同步更新商品表里的供应商信息
        Item item = new Item();
        item.setCategoryId(bo.getId());
        item.setSupplierId(bo.getSupplierId());
        item.setCategoryCode(entity.getCategoryCode());
        itemDao.updateSupplierAndCategoryCode(item);
    }

    private String getParentCode(String pid) {
        String code = "";
        if (StrUtil.isNotEmpty(pid)) {
            Category parent = categoryDao.selectByPrimaryKey(pid);
            code = parent.getCategoryCode() + "/";
        }
        return code;
    }

    public PageVo<CategoryVo> page(PageBo<CategorySearchBo> pageBo) {
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize(), MySqlUtil.orderBy(pageBo.getSort(), pageBo.isAsc()));
        List<Category> entities = categoryDao.selectByParam(pageBo.getParam());
        PageInfo<Category> info = new PageInfo(entities);
        List<CategoryVo> list = BeanConverUtils.convertBeanList(info.getList(), CategoryVo.class);
        return new PageVo<>(info.getTotal(), pageBo.getPage(), pageBo.getPageSize(), list);
    }

    public List<CategoryVo> tree(CategorySearchBo bo) {
        Category searchBo = BeanConverUtils.convertBean(bo, Category.class);
        List<Category> entities = categoryDao.select(searchBo);
        List<CategoryVo> categoryVos = new ArrayList<>();
        for (Category category : entities) {
            if (!StringUtils.hasText(category.getPid())) {
                CategoryVo categoryVo = BeanConverUtils.convertBean(category, CategoryVo.class);
                getDeptDictTree(entities, categoryVo);
                categoryVos.add(categoryVo);
            }
        }
        return categoryVos;
    }

    private CategoryVo getDeptDictTree(List<Category> categories, CategoryVo categoryVo) {
        List<CategoryVo> baseMenu = new ArrayList<>();
        for (Category category : categories) {
            if (categoryVo.getId().equals(category.getPid())) {
                CategoryVo categoryVo1 = BeanConverUtils.convertBean(category, CategoryVo.class);
                baseMenu.add(categoryVo1);
                getDeptDictTree(categories, categoryVo1);
            }
        }
        categoryVo.setChildren(baseMenu);
        return categoryVo;
    }


    public List<CategoryVo> index(CategorySearchBo bo) {
        List<Category> entities;
        if (!StringUtils.hasText(bo.getPid())) {
            entities = categoryMapper.findTop(bo.getProduct(), bo.getMchId());
        } else {
            entities = categoryMapper.findChildren(bo);
        }
        return entities.stream().map(this::convert).collect(Collectors.toList());
    }

    @Transactional(rollbackFor = Throwable.class)
    public void delete(String id) {
        List<Category> categories = categoryDao.getSubListByPid(id);
        ParamException.isTrue((!CollectionUtils.isEmpty(categories)), "该分类下有子分类，不能删除！");
        List<Item> list = itemDao.getListByCategoryId(id);
        ParamException.isTrue((!CollectionUtils.isEmpty(list)), "该分类下有商品，请先转移商品至其它分类下再删除！");
        categoryDao.deleteById(id);
    }

    private CategoryVo convert(Category entity) {
        CategoryVo vo = new CategoryVo();
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }

    public CategoryVo detail(String id) {
        Category entity = categoryDao.selectByPrimaryKey(id);
        if (entity == null) {
            throw new CommonException(ExceptionCode.DATA_NOT_EXISTS);
        }
        return convert(entity);
    }

    public CategoryVo getCateWithShopId(String id, String shopId) {
        Category entity = categoryDao.getCateWithShopId(id, shopId);
        if (entity == null) {
            throw new CommonException(ExceptionCode.DATA_NOT_EXISTS);
        }
        return convert(entity);
    }

    public List<CategoryVo> getByIds(List<String> ids) {
        List<Category> entities = categoryDao.selectByPrimaryKeys(ids);
        if (entities.isEmpty()) {
            return new ArrayList<>(0);
        }
        return entities.stream().map(entity -> convert(entity)).collect(Collectors.toList());
    }

    public void changeCategoryCode() {
        List<Category> list = categoryDao.getAll();
        if (!CollectionUtils.isEmpty(list)) {
            Map<String, String> map = new HashMap<>();
            for (Category category : list) {
                String code = category.getCategoryCode();
                String newCode = "";
                if (StrUtil.isNotEmpty(code)) {
                    String[] arrCode = code.split("/");
                    for (int i = 0; i < arrCode.length; i++) {
                        if (arrCode[i].startsWith("2020060800")) {
                            if (arrCode.length == 1) {
                                newCode += arrCode[i];
                            } else {
                                if (StrUtil.isNotEmpty(newCode)) {
                                    newCode += arrCode[i];
                                } else {
                                    newCode += arrCode[i] + "/";
                                }
                            }
                        } else {
                            if (arrCode[i].length() == 11) {
                                if (arrCode.length == 1) {
                                    newCode += UUIDGenerator.reverseShortUUID(arrCode[i]);
                                } else {
                                    if (StrUtil.isNotEmpty(newCode)) {
                                        newCode += UUIDGenerator.reverseShortUUID(arrCode[i]);
                                    } else {
                                        newCode += UUIDGenerator.reverseShortUUID(arrCode[i]) + "/";
                                    }
                                }
                            }
                        }
                    }
                }
                map.put(code, newCode);
            }
            if (!CollectionUtils.isEmpty(map)) {
                categoryDao.changeCategoryCode(map);
                itemDao.changeCategoryCode(map);
            }
        }
    }

    public List<CategoryVo> wbmIndex() {
        return BeanConverUtils.convertBeanList(categoryDao.findTopMall(), CategoryVo.class);
    }
}
